package com.richard.room.operator.api.utils;

import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.NumberCodec;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.richard.room.operator.api.Property;

import java.text.DecimalFormat;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: Richard
 * @createDate: 2023/8/15 21:49
 * @version: 1.0
 * @description: 工具类
 */
public final class Utils {

    static {
        //解决首字母大小写问题
        TypeUtils.compatibleWithJavaBean = true;

        //全局关闭循环引用检测
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.mask;
        JSON.DEFAULT_PARSER_FEATURE |= Feature.DisableCircularReferenceDetect.mask;

        //浮点数值序列化配置
        DecimalFormat decimalFormat = new DecimalFormat("#.################");
        decimalFormat.setGroupingUsed(false);
        SerializeConfig.getGlobalInstance().put(Double.class, new NumberCodec(decimalFormat));
        SerializeConfig.getGlobalInstance().put(Float.class, new NumberCodec(decimalFormat));
    }

    private Utils() {
    }

    /**
     * 利用正则表达式判断字符串是否是数字
     *
     * @param str 字符
     */
    public static boolean isNumeric(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]*|-[0-9]*");
        Matcher isNum = pattern.matcher(str);
        return isNum.matches();
    }

    /**
     * 验证整数和浮点数（正负整数和正负浮点数）
     *
     * @param decimals 一位或多位0-9之间的浮点数，如：1.23，233.30
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isDecimals(String decimals) {
        if (!TextUtils.isEmpty(decimals)) {
            Pattern decimalRegex = Pattern.compile("[0-9]\\d*|[0-9]\\d*.[0-9]\\d*|-[1-9]\\d*|-([0-9]\\d*.[0-9]\\d*)");
            return decimalRegex.matcher(decimals).matches();
        }
        return false;
    }

    /**
     * 验证是否属于数值数据
     */
    public static boolean isNum(Object object) {
        if (object == null) {
            return false;
        }
        return object.getClass().isAssignableFrom(short.class)
                || object.getClass().isAssignableFrom(Short.class)
                || object.getClass().isAssignableFrom(int.class)
                || object.getClass().isAssignableFrom(Integer.class)
                || object.getClass().isAssignableFrom(long.class)
                || object.getClass().isAssignableFrom(Long.class)
                || object.getClass().isAssignableFrom(float.class)
                || object.getClass().isAssignableFrom(Float.class)
                || object.getClass().isAssignableFrom(double.class)
                || object.getClass().isAssignableFrom(Double.class)
                || isDecimals(object.toString());
    }

    /**
     * 获取sql绑定参数值
     */
    public static Object getSqlValue(Object value) {
        if (value instanceof Property) {
            Property p = (Property) value;
            return String.format("%s.%s", p.tableName, p);
        }

        if (value instanceof CharSequence) {
            return String.format("'%s'", value.toString().replace("'", ""));
        }

        return value;
    }

    /**
     * 是否属于json
     */
    public static boolean isJson(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        str = str.trim();
        if (str.startsWith("{") && str.endsWith("}")) {
            return true;
        }
        return str.startsWith("[") && str.endsWith("]");
    }

    /**
     * 是否属于List json
     */
    public static boolean isListJson(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        str = str.trim();
        return str.startsWith("[") && str.endsWith("]");
    }

    /**
     * 是否属于对象实体json
     */
    public static boolean isObjectJson(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        str = str.trim();
        return str.startsWith("{") && str.endsWith("}");
    }

    public static <T> T getOrDefault(final T object, final T defaultObject) {
        if (object == null) {
            return defaultObject;
        }
        return object;
    }

    public static String getStrDefault(final String value, final String defaultValue) {
        if (TextUtils.isEmpty(value)) {
            return defaultValue;
        }
        return value;
    }

    public static String toJson(Object src) {
        return JSON.toJSONString(src);
    }

    public static <T> T toObject(Object object, Class<T> clazz) {
        try {
            if (object instanceof String) {
                return JSON.parseObject(object.toString(), clazz);
            }
            return JSON.parseObject(toJson(object), clazz);
        } catch (Exception ex) {
            return null;
        }
    }

    public static <T> List<T> toObjectList(Object object, Class<T> clazz) {
        try {
            if (object instanceof String) {
                return JSON.parseArray(object.toString(), clazz);
            }
            return JSON.parseArray(toJson(object), clazz);
        } catch (Exception ex) {
            return null;
        }
    }

    public static JSONObject toJSONObject(Object object) {
        try {
            if (object instanceof String) {
                return JSON.parseObject(object.toString());
            }
            return JSON.parseObject(toJson(object));
        } catch (Exception ex) {
            return null;
        }
    }

    public static JSONArray toJSONArray(Object jsonArray) {
        try {
            if (jsonArray instanceof String) {
                return JSONArray.parseArray(jsonArray.toString());
            } else {
                return JSONArray.parseArray(toJson(jsonArray));
            }
        } catch (Exception ex) {
            return null;
        }
    }
}
